package com.example.month11.indicator;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;

import com.example.recyclerview01.R;

import androidx.viewpager.widget.ViewPager;

/**
 * 自定义ScrollView，ViewPager指示器。
 * 自定义属性，indicatorItem宽度
 * 底部Fragment左右滑动切换，顶部View对应的更新当前选中的item。并让当前item显示在最中间。
 * 点击顶部的item，下面Fragment对应的切换；
 */
public class TrackIndicatorView extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
    // 适配器设计模式-Adapter
    private IndicatorAdapter mAdapter;

    private int mTabVisibleNums = 0; // 一屏幕显示可见显示多少个item
    private int mItemWidth; // 元素宽度
    private ViewPager mViewPager;
    private int mCurrentPosition = 0; // 当前位置，默认位置0
    private IndicatorGroupView mIndicatorGroup;
    // 是否是滚动，解决点击item抖动的问题。
    private boolean mIsExecuteScroll = false;
    private boolean mSmoothScroll;

    public TrackIndicatorView(Context context) {
        this(context, null);
    }

    public TrackIndicatorView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TrackIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 3.初始化指示器条目的容器
        mIndicatorGroup = new IndicatorGroupView(context);
        addView(mIndicatorGroup); // 只能添加一个子容器
        initAttribute(context, attrs);
    }

    // 4.初始化自定义属性
    private void initAttribute(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TrackIndicatorView);
        mTabVisibleNums = typedArray.getColor(R.styleable.TrackIndicatorView_tabVisibleNums, mTabVisibleNums);
        typedArray.recycle();
    }

    // 1.设置适配器
    public void setAdapter(IndicatorAdapter adapter) {
        if (adapter == null) {
            throw new NullPointerException("adapter is null!");
        }
        this.mAdapter = adapter;

        // 动态的添加子view.
        int itemCount = mAdapter.getCount();
        for (int i = 0; i < itemCount; i++) {
            View itemView = mAdapter.getView(i, mIndicatorGroup);
            itemView.setBackgroundColor(Color.LTGRAY);

            mIndicatorGroup.addItemView(itemView);
            // 7.设置点击事件,让Indicator与ViewPager一起联动。
            if (mViewPager != null) {
                switchItemClick(itemView, i);
            }
        }
        // 7.默认选中第一个位置
        mAdapter.highLightIndicator(mIndicatorGroup.getItemAt(0));
    }

    /**
     * 7.设置点击事件,让Indicator与ViewPager一起联动。
     *
     * @param itemView
     * @param position
     */
    private void switchItemClick(View itemView, final int position) {
        itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // mSmoothScroll为false，表示点击tab切换，不需要动画效果。
                mViewPager.setCurrentItem(position, mSmoothScroll);
                // 移动底部指示器
                smoothScrollIndicator(position);
                // 移动下标
                mIndicatorGroup.scrollBottomTrack(position);
            }
        });
    }

    // 点击item：平滑的滚动底部指示器
    private void smoothScrollIndicator(int position) {
        // 当前总的位置
        float totalScroll = (position) * mItemWidth;
        // 往左边的偏移量，让item显示在屏幕最中间。
        int offsetScroll = (getWidth() - mItemWidth) / 2;
        // 计算最终偏移量
        int finalScroll = (int) (totalScroll - offsetScroll);
        // X轴方向，滚动
        smoothScrollTo(finalScroll, 0);
    }

    /**
     * 6. 处理联动, 当前指示器要居中。
     *
     * @param adapter
     * @param viewPager
     */
    public void setAdapter(IndicatorAdapter adapter, ViewPager viewPager) {
        setAdapter(adapter, viewPager, true);
    }

    public void setAdapter(IndicatorAdapter adapter, ViewPager viewPager, boolean smoothScroll) {
        this.mSmoothScroll = smoothScroll;
        if (viewPager == null) {
            throw new NullPointerException("viewPager is null!");
        }
        this.mViewPager = viewPager;
        mViewPager.addOnPageChangeListener(this);
        setAdapter(adapter);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        // 5.指定item的宽度
        if (changed) {
            int parentWidth = getWidth();
            // int itemWidth = parentWidth / mTabVisibleNums;
            mItemWidth = getItemWidth();
            for (int i = 0; i < mAdapter.getCount(); i++) {
                ViewGroup.LayoutParams layoutParams = mIndicatorGroup.getItemAt(i).getLayoutParams();
                layoutParams.width = mItemWidth;
                layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; // 与父容器一样高。
                mIndicatorGroup.getItemAt(i).setLayoutParams(layoutParams);
            }
            // 8.添加底部跟踪的指示器
            mIndicatorGroup.addBottomTrackView(mAdapter.getBottomTrackView(), mItemWidth);
        }
    }

    /**
     * 5.获取item宽度
     * 如果没有配置mTabVisibleNums，那么宽度就是item里面最宽的。
     * 如果宽度和任然不足一屏幕宽，那么总共占用一屏宽。
     *
     * @return
     */
    private int getItemWidth() {
        int parentWidth = getWidth();
        // 指定了一屏幕显示多少item
        if (mTabVisibleNums != 0) {
            return parentWidth / mTabVisibleNums;
        }
        // 没有指定,总宽度=最大item宽度*数量
        int maxItemWidth = 0;
        for (int i = 0; i < mAdapter.getCount(); i++) {
            int currentItemWidth = mIndicatorGroup.getItemAt(i).getWidth();
            maxItemWidth = Math.max(currentItemWidth, maxItemWidth);
        }
        int itemWidth = maxItemWidth;
        int allWidth = mAdapter.getCount() * itemWidth;
        // 所有条目宽和，是否大于一屏幕
        if (allWidth < parentWidth) {
            itemWidth = parentWidth / mAdapter.getCount();
        }
        return itemWidth;
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (mIsExecuteScroll) {
            // 6.滚动的时候，不断地调用
            scrollCurrentIndicator(position, positionOffset);
            mIndicatorGroup.scrollBottomTrack(position, positionOffset);
            // 如果是点击，就不执行onPageScrolled方法。
        }
    }

    // 滚动当前的顶部指示器。让当前的item在上面的最中间显示。
    private void scrollCurrentIndicator(int position, float positionOffset) {
        // 当前总的位置
        float totalScroll = (position + positionOffset) * mItemWidth;
        // 往左边的偏移量，让item显示在屏幕最中间。
        int offsetScroll = (getWidth() - mItemWidth) / 2;
        // 计算最终偏移量
        int finalScroll = (int) (totalScroll - offsetScroll);
        // X轴方向，滚动
        scrollTo(finalScroll, 0);
    }

    @Override
    public void onPageSelected(int position) {
        // 将当前位置高亮，上一个位置恢复。
        mAdapter.restoreIndicator(mIndicatorGroup.getItemAt(mCurrentPosition));
        mAdapter.highLightIndicator(mIndicatorGroup.getItemAt(position));
        mCurrentPosition = position;
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == 1) {
            mIsExecuteScroll = true;
        }
        if (state == 0) {
            mIsExecuteScroll = false;
        }
    }
}
